3 * Copyright (c) 2016 Mike Lischke
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #import <XCTest/XCTest.h>
32 #include "ANTLRInputStream.h"
33 #include "Exceptions.h"
35 #include "UnbufferedTokenStream.h"
36 #include "StringUtils.h"
38 using namespace antlrcpp;
39 using namespace antlr4;
40 using namespace antlr4::misc;
42 @interface InputHandlingTests : XCTestCase
46 @implementation InputHandlingTests
50 // Put setup code here. This method is called before the invocation of each test method in the class.
54 // Put teardown code here. This method is called after the invocation of each test method in the class.
58 - (void)testANTLRInputStreamCreation {
59 ANTLRInputStream stream1;
60 XCTAssert(stream1.toString().empty());
61 XCTAssertEqual(stream1.index(), 0U);
63 ANTLRInputStream stream2("To be or not to be");
64 XCTAssert(stream2.toString() == "To be or not to be");
65 XCTAssertEqual(stream2.index(), 0U);
66 XCTAssertEqual(stream2.size(), 18U);
68 char data[] = "Lorem ipsum dolor sit amet";
69 ANTLRInputStream stream3(data, sizeof(data) / sizeof(data[0]));
70 XCTAssert(stream3.toString() == std::string("Lorem ipsum dolor sit amet\0", 27));
71 XCTAssertEqual(stream3.index(), 0U);
72 XCTAssertEqual(stream3.size(), 27U);
74 std::stringstream input("Lorem ipsum dolor sit amet");
75 ANTLRInputStream stream4(input);
76 std::string content = stream4.toString();
77 XCTAssertEqual(content, "Lorem ipsum dolor sit amet"); // Now as utf-8 string.
78 XCTAssertEqual(stream4.index(), 0U);
79 XCTAssertEqual(stream4.size(), 26U);
81 std::string longString(33333, 'a');
82 input.str(longString);
84 XCTAssertEqual(stream4.index(), 0U);
85 XCTAssertEqual(stream4.size(), 33333U);
89 XCTAssertEqual(stream4.size(), 0U);
92 - (void)testANTLRInputStreamUse {
93 std::string text(u8"🚧Lorem ipsum dolor sit amet🕶");
94 std::u32string wtext = utf8_to_utf32(text.c_str(), text.c_str() + text.size()); // Convert to UTF-32.
95 ANTLRInputStream stream(text);
96 XCTAssertEqual(stream.index(), 0U);
97 XCTAssertEqual(stream.size(), wtext.size());
99 for (size_t i = 0; i < stream.size(); ++i) {
101 XCTAssertEqual(stream.index(), i + 1);
107 } catch (IllegalStateException &e) {
109 std::string message = e.what();
110 XCTAssertEqual(message, "cannot consume EOF");
113 XCTAssertEqual(stream.index(), wtext.size());
115 XCTAssertEqual(stream.index(), 0U);
117 XCTAssertEqual(stream.LA(0), 0ULL);
118 for (size_t i = 1; i < wtext.size(); ++i) {
119 XCTAssertEqual(stream.LA(static_cast<ssize_t>(i)), wtext[i - 1]); // LA(1) means: current char.
120 XCTAssertEqual(stream.LT(static_cast<ssize_t>(i)), wtext[i - 1]); // LT is mapped to LA.
121 XCTAssertEqual(stream.index(), 0U); // No consumption when looking ahead.
124 stream.seek(wtext.size() - 1);
125 XCTAssertEqual(stream.index(), wtext.size() - 1);
127 stream.seek(wtext.size() / 2);
128 XCTAssertEqual(stream.index(), wtext.size() / 2);
130 stream.seek(wtext.size() - 1);
131 for (ssize_t i = 1; i < static_cast<ssize_t>(wtext.size()) - 1; ++i) {
132 XCTAssertEqual(stream.LA(-i), wtext[wtext.size() - i - 1]); // LA(-1) means: previous char.
133 XCTAssertEqual(stream.LT(-i), wtext[wtext.size() - i - 1]); // LT is mapped to LA.
134 XCTAssertEqual(stream.index(), wtext.size() - 1); // No consumption when looking ahead.
137 XCTAssertEqual(stream.LA(-10000), IntStream::EOF);
139 // Mark and release do nothing.
141 XCTAssertEqual(stream.index(), 0U);
142 ssize_t marker = stream.mark();
143 XCTAssertEqual(marker, -1);
145 XCTAssertEqual(stream.index(), 10U);
146 XCTAssertEqual(stream.mark(), -1);
148 stream.release(marker);
149 XCTAssertEqual(stream.index(), 10U);
151 misc::Interval interval1(2, 10UL); // From - to, inclusive.
152 std::string output = stream.getText(interval1);
153 std::string sub = utf32_to_utf8(wtext.substr(2, 9));
154 XCTAssertEqual(output, sub);
156 misc::Interval interval2(200, 10UL); // Start beyond bounds.
157 output = stream.getText(interval2);
158 XCTAssert(output.empty());
160 misc::Interval interval3(0, 200UL); // End beyond bounds.
161 output = stream.getText(interval3);
162 XCTAssertEqual(output, text);
164 stream.name = "unit tests"; // Quite useless test, as "name" is a public field.
165 XCTAssertEqual(stream.getSourceName(), "unit tests");
168 - (void)testUnbufferedTokenSteam {
169 //UnbufferedTokenStream stream;